package com.iretailer.report.easyexcel.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.iretailer.report.common.InternationalMessage;
import com.iretailer.report.easyexcel.data.UserData;
import com.iretailer.report.error.ImportException;
import com.iretailer.report.model.Companies;
import com.iretailer.report.model.Config;
import com.iretailer.report.model.Role;
import com.iretailer.report.model.User;
import com.iretailer.report.service.CompanyService;
import com.iretailer.report.service.ConfigService;
import com.iretailer.report.service.RoleService;
import com.iretailer.report.service.UserService;
import com.iretailer.report.util.*;
import lombok.Getter;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;


@Slf4j
/*
 * @program: report
 * @description:
 * @author: Bennie
 * @create: 2020-06-15 12:34
 **/
public class UserDataListener extends AnalysisEventListener<UserData> {

    private final UserService userService;

    private final CompanyService companyService;

    private final RoleService roleService;

    private final String language;

    private final User currentUser;

    private final ConfigService configService;

    public UserDataListener(HttpServletRequest request) {
        this.userService = SpringUtils.getBean(UserService.class);
        this.roleService = SpringUtils.getBean(RoleService.class);
        this.companyService = SpringUtils.getBean(CompanyService.class);
        this.configService = SpringUtils.getBean(ConfigService.class);
        currentUser = SecurityUserUtil.currentUser(request);
        language = SecurityUserUtil.userLanguage(request);
    }

    private List<User> userList = new ArrayList<>();

    @Getter
    private List<UserData> userDataList = new ArrayList<>();

    @SneakyThrows
    @Override
    public void invoke(UserData data, AnalysisContext context) {


        String loginName = data.getLoginName();
        if (StringUtils.isBlank(loginName)) {
            throw new ImportException(InternationalMessage.EMPTY_LOGIN_NAME.getByLanguage(language));
        }
        int userCount = userService.count(new QueryWrapper<User>().lambda().eq(User::getUserCode, loginName));
        if (userCount > 0) {
            throw new ImportException(InternationalMessage.EXISTS_LOGIN_NAME.getByLanguage(language) + "\t" + loginName);
        }
        String companyName = data.getCompanyName();
        if (StringUtils.isBlank(companyName)) {
            throw new ImportException(InternationalMessage.EMPTY_COMPANY_NAME.getByLanguage(language));
        }
        List<Companies> companies = companyService.list(new QueryWrapper<Companies>().lambda().eq(Companies::getName, companyName));
        if (companies.size() != 1) {
            throw new ImportException(InternationalMessage.INVALID_COMPANY_NAME.getByLanguage(language) + "\t" + companyName);
        }
        String username = data.getUserName();
        if (StringUtils.isBlank(username)) {
            throw new ImportException(InternationalMessage.EMPTY_USER_NAME.getByLanguage(language));
        }
        String roleName = data.getRoleName();
        if (StringUtils.isBlank(roleName)) {
            throw new ImportException(InternationalMessage.EMPTY_ROLE_NAME.getByLanguage(language));
        }
        List<Role> roles = roleService.list(new QueryWrapper<Role>().lambda().eq(Role::getName, roleName));
        if (roles.size() != 1) {
            throw new ImportException(InternationalMessage.INVALID_ROLE_NAME.getByLanguage(language) + "\t" + roleName);
        }
        String password = data.getPassword();
        if (StringUtils.isBlank(password)) {
            throw new ImportException(InternationalMessage.EMPTY_PASSWORD.getByLanguage(language));
        }
        Config pr = configService.getOne(new QueryWrapper<Config>().lambda().eq(Config::getConfigKey, "password_regex"));
        if (pr != null && StringUtil.notEmpty(pr.getConfigValue())) {
            List<Map<String, Object>> prMaps = JsonUtil.json2list(pr.getConfigValue());
            for (Map<String, Object> prMap : prMaps) {
                String regex = (String) prMap.get("regex");
                String errorMsg = (String) prMap.get("errorMsg");
                if (!Pattern.matches(regex, password)) {
                    throw new ImportException(String.format("【%s】%s", username, errorMsg));
                }
            }
        }
        User user = new User();
        LocalDateTime now = LocalDateTime.now();
        user.setCreateTime(now);
        user.setUserPwd(MD5Util.getMd5(password));
        user.setId(IdWorker.get32UUID());
        user.setUserCode(loginName);
        user.setName(username);
        user.setCreateUser("Excel import by " + currentUser.getName());
        user.setParentId(currentUser.getId());
        user.setCompanyId(companies.get(0).getId());
        user.setRoleId(roles.get(0).getId());
        user.setLanguage(language);
        user.setIsLock(0);
        user.setLockTime(now);
        this.userDataList.add(data);
        this.userList.add(user);
    }

    @Override
    @Transactional
    public void doAfterAllAnalysed(AnalysisContext context) {
        this.userService.saveBatch(userList);
        log.info("Excel 用户数据导入成功!");
    }
}